﻿using IdentityModel;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using NLog;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Xlit.Example.Business.Services;
using Xlit.Project;
using Xlit.Project.Model.SysAccountDto;

namespace Xlit.Example.Controllers
{
    /// <summary>
    ///  当前登录用户
    /// </summary>
    [Route("api")]
    public class LoginUserController : Xlit.Project.Mvc.Controller.ControllerBase
    {
        /// <summary>
        ///  系统账户
        /// </summary>
        public SysAccountService SysAccountService { get; set; }

        /// <summary>
        ///  登入
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("login")]
        [AllowAnonymous]
        public IActionResult Login([FromBody] SignInInput input)
        {
            var user = SysAccountService.Login(input.Credential, input.Password);
            var userid = user.Id.ToString();

            // 登录
            var claimIdentity = GetClaimsIdentity(userid);
            // 制作并返回 Token
            return Success(data: GetToken(claimIdentity));
        }

        /// <summary>
        ///  登出
        /// </summary>
        /// <returns></returns>
        [HttpPost("logout")]
        [AllowAnonymous]
        public IActionResult Logout()
        {
            return Success();
        }

        /// <summary>
        ///  我的账号信息
        /// </summary>
        /// <returns></returns>
        [HttpGet("my/info")]
        public IActionResult MyInfo()
        {
            var user = SysAccountService.Get(CurrentUser.Id);
            var output = AutoMapper.Mapper.Map<UserInfoOutput>(user);
            return Success(data: output);
        }

        /// <summary>
        ///  更新我的账号信息
        /// </summary>
        /// <returns></returns>
        [HttpPost("my/info")]
        public IActionResult UpdateMyInfo()
        {
            return Success("更新成功");
        }

        /// <summary>
        ///  我的菜单
        /// </summary>
        /// <returns></returns>
        [HttpGet("my/menus")]
        public IActionResult MyMenus()
        {
            var output = SysAccountService.GetUserMenu(CurrentUser.Id);
            return Success("获取成功", output);
        }

        /// <summary>
        ///  我的通知
        /// </summary>
        /// <returns></returns>
        [HttpGet("my/message")]
        public IActionResult MyMessage()
        {
            return Success();
        }

        /// <summary>
        ///  头像上传
        /// </summary>
        /// <param name="file">文件</param>
        /// <returns>头像存放路径</returns>
        [HttpPost("my/photo")]
        public IActionResult PhotoUpload([FromForm] IFormFile file)
        {
            string path = Upload(file, @"upload\user");
            return Success(data: path);
        }

        /// <summary>
        ///  更新我的密码
        /// </summary>
        /// <returns></returns>
        [HttpPost("my/password")]
        public IActionResult ModifyPassword([FromBody] UpdatePasswordInput input)
        {
            SysAccountService
               .UpdatePassword(CurrentUser.Id, input);
            return Success("更新成功");
        }

        /// <summary>
        ///  制作身份凭证
        /// </summary>
        /// <param name="userid"></param>
        /// <returns></returns>
        [NonAction]
        protected ClaimsIdentity GetClaimsIdentity(string userid)
        {
            IList<Claim> claimList = new List<Claim>()
            {
                new Claim(JwtClaimTypes.Audience, "api"),
                new Claim(JwtClaimTypes.Id, userid)
            };
            return new ClaimsIdentity(claimList, JwtBearerDefaults.AuthenticationScheme);
        }

        /// <summary>
        ///  加密身份凭证制作 Token
        /// </summary>
        /// <param name="claimIdentity"></param>
        /// <returns></returns>
        [NonAction]
        protected string GetToken(ClaimsIdentity claimIdentity)
        {
            var securityKeyByte = Encoding.ASCII.GetBytes(DefineVar.ISSUER_SIGNING_KEY);
            var authTime = DateTime.UtcNow;
            var expiresAt = authTime.AddDays(30);

            var tokenDescriptor = new SecurityTokenDescriptor()
            {
                Subject = claimIdentity,
                Expires = expiresAt,
                SigningCredentials = new SigningCredentials(
                    new SymmetricSecurityKey(securityKeyByte),
                    SecurityAlgorithms.HmacSha256Signature)
            };

            var tokenHandler = new JwtSecurityTokenHandler();
            var token = tokenHandler.CreateToken(tokenDescriptor);
            var tokenString = tokenHandler.WriteToken(token);
            return tokenString;
        }
    }
}